Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MI32 legacy: track BLE devices with RPA / updates to esp-nimble-cpp #22300

Merged
merged 1 commit into from
Oct 16, 2024

Conversation

Staars
Copy link
Contributor

@Staars Staars commented Oct 15, 2024

Description:

Allows tracking of Apple devices with resolvable random private addresses, which should work for all kind of other modern devices with this address type too.

This will simply treat a given key for a non-Xiaomi device as a so called IRK. This key can be retrieved with a Berry script (will be posted in the comments).
Needs following build flags:

build_flags                 = ${env:tasmota32_base.build_flags}
                              -DFIRMWARE_BLUETOOTH
                              -DUSE_MI_EXT_GUI
                              -DCONFIG_BT_NIMBLE_NVS_PERSIST=y
                              -DOTA_URL='""'

This PR includes needed updates for esp-nimble-cpp, that do still compile with the main Bluetooth driver of Tasmota but need testing. The most recent included commit is: h2zero/esp-nimble-cpp@a92149a

Checklist:

  • The pull request is done against the latest development branch
  • Only relevant files were touched
  • Only one feature/fix was added per PR and the code change compiles without warnings
  • The code change is tested and works with Tasmota core ESP8266 V.2.7.8
  • The code change is tested and works with Tasmota core ESP32 V.3.1.0.240926
  • I accept the CLA.

NOTE: The code change must pass CI tests. Your PR cannot be merged unless tests pass

@Staars
Copy link
Contributor Author

Staars commented Oct 15, 2024

Steps to track an iPhone:

  1. Paste the following code to the Berry console and run it:
#------------------------------------------------------------------------------
- Fake heartrate server to get IRK
-------------------------------------------------------------------------------#

import BLE
var cbuf = bytes(-255)

class IRK : Driver
    var current_func, next_func

    def init()
        import cb
        var cbp = cb.gen_cb(/e,o,u,h->self.cb(e,o,u,h))
        BLE.serv_cb(cbp,cbuf)
        self.current_func = /->self.add_bpm()
        log("BLE: start hearrate server",1)
    end

    def every_50ms()
        self.current_func()
    end

    def wait()

    end

    def then(func)
        # save function pointers for callback, typically expecting a closure
        self.next_func = func
        self.current_func = /->self.wait()
    end

    def updateMI32cfg()
        import json
        import string
        var i = BLE.info()
        var d = {}
        d["MAC"] = string.tr(i["connection"]["peerID_addr"],":","")
        d["name"] = i["connection"]["name"]
        try
            d["key"] = bytes(i["connection"]["IRK"]).reverse().tohex()
        except ..
            log("M32: could not get IRK, is firmware configured with -DCONFIG_BT_NIMBLE_NVS_PERSIST=y ??",1)
            return
        end
        d["PID"] = "0000"
        var j = []
        var f
        try
            f = open("mi32cfg","r")
            j = json.load(f.read())
            j.push(d)
            f.close()
        except ..
            j.push(d)
        end
        f = open("mi32cfg","w")
        f.write(json.dump(j))
        f.close()
        log(j.tostring())
    end

    def cb(error,op,uuid,handle)
        import persist
        print(error,op,uuid,handle)
        if op == 201
            print("Handles:",cbuf[1..cbuf[0]])
        elif op == 221

        elif op == 222

        elif op == 227
            print("MAC:",cbuf[1..cbuf[0]])
        elif op == 228
            log("Disconnected")
        elif op == 229
            print("Status:",cbuf[1..cbuf[0]])
        elif op == 230
            var name = BLE.info()["connection"]["name"]
            print("Authenticated:",name)
            persist.setmember(name,cbuf[1..cbuf[0]].tob64())
            self.updateMI32cfg()
        end
        if error == 0 && op != 229
            self.current_func = self.next_func
        end
    end

    # custom section
    def add_bpm()
        BLE.set_svc("180D") # Heart Rate Service
        BLE.set_chr("2A37") # Heart Rate Measurements Characteristics (BPM)
        cbuf.setbytes(0,bytes("0100"))
        BLE.run(211,true, 1554) # READ | READ_ENC | NOTIFY |  READ_AUTHENT
        self.then(/->self.add_loc())
    end
    def add_loc()
        BLE.set_chr("2A38") # Body Sensor Location 
        var b = bytes().fromstring("Please enter PIN first.")
        cbuf.setbytes(1,b)
        cbuf[0] = size(b)
        BLE.run(211)
        self.then(/->self.add_ScanResp())
    end

    def add_ADV()
        var payload = bytes("02010603020D18") # flags and heartrate svc uuid
        cbuf[0] = size(payload)
        cbuf.setbytes(1,payload)
        BLE.run(201)
        self.then(/->self.wait())
    end

    def add_ScanResp()
        var local_name = "Tasmota BLE"
        var payload = bytes("0201060008") + bytes().fromstring(local_name) # 00 before 08  is a placeholder
        payload[3] = size(local_name) + 1 # ..set size of name
        cbuf[0] = size(payload)
        cbuf.setbytes(1,payload)
        BLE.run(202)
        self.then(/->self.add_ADV())
    end

end

var irk = IRK()
tasmota.add_driver(irk)
  1. This will create a fake heart rate sensor the should show up in the BLE part of the system setting, but the name could be "Tasmota BLE" or on my German iPhone "Zubehör" or any comparable name in other languages. Press on it to pair.

  2. This should get the IRK and the identity address and the Berry driver will add this to the mi32cfg file. The name of your BLE devices will be added too.

  3. Reboot the ESP.

@Jason2866 Jason2866 merged commit e39f1cc into arendst:development Oct 16, 2024
59 checks passed
josef109 pushed a commit to josef109/Tasmota that referenced this pull request Nov 7, 2024
josef109 pushed a commit to josef109/Tasmota that referenced this pull request Nov 10, 2024
@Staars Staars deleted the BLE_RPA branch December 18, 2024 19:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants